import { ElMessage } from "element-plus";
import type { CellStyle } from "element-plus";
import { toUnderline, getTableHeight } from "@/utils/util";
import { onMounted } from "vue";
import { http } from "@/utils/http";
import { getRandNodeId } from "@/utils/process";

/**
 * 表格组件基础配置属性
 */
export interface BasicTableProps {
  // 是否在创建页面时即调用数据列表接口，默认为true
  autoLoad?: boolean;
  // 是否需要分页，默认为true
  isPage?: boolean;
  // 查询条件表单对象，类型为any
  queryForm?: any;
  // 是否多选
  multiple?: boolean;
  // 表格高度，类型为number
  height?: number;
  // 数据列表数组
  dataList?: any[];
  // 分页属性对象
  pagination?: Pagination;
  // 数据列表，loading状态标志，默认为false
  loading?: boolean;
  // 数据列表多选项数组
  dataSelections?: any[];
  // 数据列表查询接口api方法，接收任意数量参数，返回Promise
  queryFunction?: (...arg: any) => Promise<any>;
  // 排序字段数组
  descs?: string[];
  // 排序方式数组
  ascs?: string[];
  // props属性对象，类型为any
  props?: any;
  // 回调事件，类型为any
  onLoaded?: (dataList?: any[]) => void;
  onReseted?: (arg?: any) => void;
  // 转义数据
  dicData?: any;
}

/**
 * 表格样式。
 */
export interface TableStyle {
  cellStyle: CellStyle<any>;
  headerCellStyle: CellStyle<any>;
}

/**
 * 分页属性配置接口
 */
export interface Pagination {
  // 当前页码，默认为1
  current?: number;
  // 每页显示条数，默认为10
  size?: number;
  // 总条数，默认为0
  total?: number;
  // 每页显示条数选择器的选项数组，默认为[10,20,30,40]
  pageSizes?: any[];
  // 分页组件布局方式，可选值有 total,sizes,prev,jump,next，默认为'total,sizes,prev,jump,next'
  layout?: string;
}

export function useTable(options?: BasicTableProps, refObject?: object) {
  const tableRef = ref(null);

  const defaultHeight = getTableHeight(1, true, true) - 10;

  const defaultOptions: BasicTableProps = {
    // 列表数据是否正在加载中，默认为false
    loading: false,
    // 是否需要自动请求创建接口来获取表格数据，默认为true
    autoLoad: false,
    // 是否展示分页组件，默认为true
    isPage: true,
    // 是否多选,默认为true
    multiple: false,
    // 表格默认高度
    height: getTableHeight(1, true, true) - 10,
    // 查询表单对象，用于提交条件查询时的参数传递，默认为空对象
    queryForm: {},
    // 表格展示的数据数组，默认为空数组
    dataList: [],
    // 分页组件属性配置，如当前页码、每页展示数据条数等，默认值为 {current:1, size:10,total:0,pageSizes:[1, 10, 20, 50, 100, 200],layout:'total, sizes, prev, pager, next, jumper'}
    pagination: {
      current: 1,
      size: 10,
      total: 0,
      pageSizes: [1, 10, 20, 50, 100, 200],
      layout: "total, sizes, prev, pager, next, jumper"
    } as Pagination,
    // 当前选中的数据项，默认为空数组
    dataSelections: [],
    // 排序时使用的字段名数组，如 ['id','name']，默认为空数组
    descs: [],
    // 排序方向数组，如 ['asc', 'desc']，默认为空数组
    ascs: [],
    // props属性配置对象，用于自定义数据属性，默认值为 {item:'records',totalCount:'total'}
    props: {
      item: "records",
      totalCount: "total",
      primaryColumn: "id"
    }
  };

  /**
   * 合并默认属性配置和自定义属性配置
   * @param options 默认属性配置对象
   * @param props 自定义属性配置对象
   * @returns 合并后的属性配置对象
   */
  const mergeDefaultOptions = (options: any, props: any): BasicTableProps => {
    for (const key in options) {
      if (!Object.getOwnPropertyDescriptor(props, key)) {
        props[key] = options[key];
      }
    }
    for (const key in props.queryForm) {
      initQueryForm[key] = props.queryForm[key];
    }
    return props;
  };

  const initQueryForm = {};

  // 覆盖默认值
  const instance = mergeDefaultOptions(defaultOptions, options);

  /**
   * 发起分页查询，并设置表格数据和分页信息
   */
  const query = async () => {
    // 判断是否存在instance.queryFunction属性
    if (instance.queryFunction) {
      try {
        // 开始加载数据，设置instance.loading为true
        instance.loading = true;
        // 调用instance.queryFunction方法发起分页查询
        await instance
          .queryFunction({
            ...instance.queryForm,
            pageNo: instance.pagination?.current,
            pageSize: instance.pagination?.size,
            descs: instance.descs.join(","),
            ascs: instance.ascs.join(",")
          })
          .then(res => {
            if (res) {
              if (res.code && res.code !== 200) {
                ElMessage.error(res.msg);
                return;
              }
              // 设置表格展示的数据数组
              instance.dataList = instance.isPage
                ? res[instance.props.item]
                : res[instance.props.item];
              console.log("query", instance.dataList);
              // 设置分页信息中的总数据条数
              instance.pagination!.total = instance.isPage
                ? res[instance.props.totalCount]
                : 0;
              // 执行回调事件
              if (instance.onLoaded) instance.onLoaded(instance.dataList);
            }
          });
      } catch (err: any) {
        // 捕获异常并显示错误提示
        ElMessage.error(err);
      } finally {
        // 结束加载数据，设置instance.loading为false
        instance.loading = false;
      }
    }
  };

  onMounted(() => {
    if (refObject) {
      tableRef.value = refObject;
    }
    if (instance.autoLoad) {
      query();
    }
  });

  /**
   * 分页大小改变事件处理函数
   * @param val 新的分页大小
   */
  const handleSizeChange = (val: number) => {
    // 修改instance.pagination中的size属性
    instance.pagination!.size = val;
    // 再次发起查询操作
    query();
  };

  const handleSelectionChange = (rows: any[]) => {
    instance.dataSelections = rows;
  };

  const handleRowClick = (row: any) => {
    if (tableRef && tableRef.value) {
      if (!instance.multiple) {
        tableRef.value.value.clearSelection();
        tableRef.value.value.toggleRowSelection(row);
      } else {
        if (instance.dataSelections && instance.dataSelections.length > 0) {
          const exists = instance.dataSelections.some(targetitem => {
            if (
              targetitem[instance.props.primaryColumn] ===
              row[instance.props.primaryColumn]
            ) {
              return true;
            }
          });
          tableRef.value.value.toggleRowSelection(row, !exists);
        } else {
          tableRef.value.value.toggleRowSelection(row);
        }
      }
    }
  };

  /**
   * 当前页码改变事件处理函数
   * @param val 新的页码
   */
  const handleCurrentChange = (val: number) => {
    // 修改instance.pagination中的current属性
    instance.pagination!.current = val;
    // 再次发起查询操作
    query();
  };

  // 排序触发事件
  const handleSortChange = (column: any) => {
    let prop = toUnderline(column.prop);
    if (!prop && column.column.property) {
      prop = toUnderline(column.column.property);
    }
    if (column.order === "descending") {
      instance.descs?.push(prop);
      if (instance.ascs!.indexOf(prop) >= 0) {
        instance.ascs?.splice(instance.ascs.indexOf(prop), 1);
      }
    } else if (column.order === "ascending") {
      instance.ascs?.push(prop);
      if (instance.descs!.indexOf(prop) >= 0) {
        instance.descs?.splice(instance.descs.indexOf(prop), 1);
      }
    } else {
      if (instance.ascs!.indexOf(prop) >= 0) {
        instance.ascs?.splice(instance.ascs.indexOf(prop), 1);
      }
      if (instance.descs!.indexOf(prop) >= 0) {
        instance.descs?.splice(instance.descs.indexOf(prop), 1);
      }
    }
    query();
  };

  /**
   * 获取数据列表，并可选择是否刷新当前页码
   * 刷新后不跳转第一页，则入参 getDataList(false)
   * @param refresh 是否刷新当前页码
   */
  const queryTableData = async (
    params?: any,
    refresh: boolean = false,
    paramsOverride: boolean = false
  ) => {
    // 如果需要刷新，则将instance.pagination.current重置为1
    if (refresh) {
      instance.pagination!.current = 1;
    }
    // 再次发起查询操作
    if (params && Object.getOwnPropertyNames(params).length > 0) {
      for (const key in params) {
        if (Object.prototype.hasOwnProperty.call(params, key)) {
          instance.queryForm[key] = params[key];
        }
        if (paramsOverride) {
          if (Object.prototype.hasOwnProperty.call(initQueryForm, key)) {
            initQueryForm[key] = params[key];
          }
        }
      }
      // 再次发起查询操作
      await query();
    } else {
      // 再次发起查询操作
      await query();
    }
  };

  const handleResetQuery = () => {
    instance.queryForm = {};
    for (const key in initQueryForm) {
      instance.queryForm[key] = initQueryForm[key];
    }
    if (instance.onReseted) instance.onReseted();
    query();
  };

  const handleReset = () => {
    instance.dataList = [];
    instance.dataSelections = [];
    for (const key in initQueryForm) {
      instance.queryForm[key] = initQueryForm[key];
    }
  };

  const handleToggleMultiple = multiple => {
    instance.multiple = multiple;
  };

  /**
   * 下载文件
   * @param url 文件下载地址
   * @param query 请求参数（可能包含token）
   * @param fileName 文件名
   * @returns 返回一个Promise对象，用于异步处理结果
   */
  const downBlobFile = (url: string, params: any, fileName: string) => {
    const loadingInstance = ElLoading.service();
    http
      .request<BlobPart>("post", url, {
        data: params,
        responseType: "blob"
      })
      .then(res => {
        const blob = new Blob([res], { type: "application/x-xls" });
        // 将链接地址字符内容转变成blob地址
        const link = document.createElement("a");
        link.href = URL.createObjectURL(blob);
        // 下载文件的名字
        link.download = fileName + getRandNodeId() + ".xls";
        link.click();
        loadingInstance.close();
      });
  };

  const handleToggleHeight = (height?: number) => {
    if (height) {
      if (instance.height != defaultHeight) {
        instance.height = instance.height - height;
      } else {
        instance.height = defaultHeight - height;
      }
    } else {
      instance.height = defaultHeight;
    }
  };

  const handleAdjustHeight = (height?: number) => {
    if (height) {
      instance.height = defaultHeight + height;
    } else {
      instance.height = defaultHeight;
    }
  };

  /**
   * 定义表格通用样式
   * @returns  css
   */
  const tableStyle: TableStyle = {
    cellStyle: {},
    headerCellStyle: {
      textAlign: "center"
    }
  };

  return {
    instance,
    tableStyle,
    queryTableData,
    handleReset,
    handleResetQuery,
    handleSizeChange,
    handleCurrentChange,
    handleSortChange,
    handleSelectionChange,
    handleToggleMultiple,
    handleRowClick,
    downBlobFile,
    handleToggleHeight,
    handleAdjustHeight
  };
}
